{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Numpy基础：数组与向量化计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = set([1,2,3,4,5])\n",
    "b = {3,4,5,6,7,8}\n",
    "x = ['1','2','3','abc']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 5}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = a.copy()\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4, 5} {3, 4, 5, 6, 7, 8} {1, 2, 3, 4, 5, 6, 7, 8}\n"
     ]
    }
   ],
   "source": [
    "c_1 = a.copy()\n",
    "c_2 = b.copy()\n",
    "c_1|c_2\n",
    "print(c_1,c_2,c_1|c_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 5, 6, 7, 8}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c =a|b\n",
    "c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4, 5, 6, 7, 8} {3, 4, 5, 6, 7, 8}\n"
     ]
    }
   ],
   "source": [
    "c_1 = a.copy()\n",
    "c_2 = b.copy()\n",
    "c_1|=c_2\n",
    "print(c_1,c_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True False\n",
      "True False\n"
     ]
    }
   ],
   "source": [
    "c_3 = {5,4,3,2,1}\n",
    "c_1 = a.copy()\n",
    "print(c_1 == a, c_1 is a)\n",
    "print(c_3 == a, c_3 is a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "根据字符串中不同字母的数量对一个字符串集合进行排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "strings = ['foo','card','bar','aaaa','abab']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[['f', 'o', 'o'], ['c', 'a', 'r', 'd'], ['b', 'a', 'r'], ['a', 'a', 'a', 'a'], ['a', 'b', 'a', 'b']]\n",
      "[{'o', 'f'}, {'r', 'a', 'd', 'c'}, {'b', 'a', 'r'}, {'a'}, {'b', 'a'}]\n",
      "[2, 4, 3, 1, 2]\n"
     ]
    }
   ],
   "source": [
    "step_1 = [list(x) for x in strings]\n",
    "step_2 = [set(list(x)) for x in strings]\n",
    "step_3 = [len(set(list(x))) for x in strings]\n",
    "print(step_1)\n",
    "print(step_2)\n",
    "print(step_3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "strings.sort(key = lambda x: len(set(list(x))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['aaaa', 'foo', 'abab', 'bar', 'card']"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3. 4. 5. 6. 7. 8.] [3 4 5 6 7 8]\n"
     ]
    }
   ],
   "source": [
    "c_15 = np.array([i for i in b], dtype = np.float64)\n",
    "d_15 = np.array([i for i in b], dtype = np.int8)\n",
    "print(c_15,d_15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "could not convert string to float: 'abc'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-29-7c995a6245f3>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mnumeric_strings\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdtype\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfloat64\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      2\u001b[0m \u001b[0mnumeric_strings\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mValueError\u001b[0m: could not convert string to float: 'abc'"
     ]
    }
   ],
   "source": [
    "numeric_strings = np.array(x, dtype = np.float64)\n",
    "numeric_strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 0., 0.],\n",
       "       [1., 1., 1., 1.],\n",
       "       [2., 2., 2., 2.],\n",
       "       [3., 3., 3., 3.],\n",
       "       [4., 4., 4., 4.],\n",
       "       [5., 5., 5., 5.],\n",
       "       [6., 6., 6., 6.],\n",
       "       [7., 7., 7., 7.]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr = np.zeros((8,4))\n",
    "for i in range(8):\n",
    "    arr[i] = i\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[4., 4., 4., 4.],\n",
       "       [3., 3., 3., 3.],\n",
       "       [0., 0., 0., 0.],\n",
       "       [6., 6., 6., 6.]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr[[4,3,0,6]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组转置和换轴"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7],\n",
       "        [ 8,  9, 10, 11]],\n",
       "\n",
       "       [[12, 13, 14, 15],\n",
       "        [16, 17, 18, 19],\n",
       "        [20, 21, 22, 23]]])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr = np.arange(24).reshape((2,3,4))\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  4,  8],\n",
       "        [ 1,  5,  9],\n",
       "        [ 2,  6, 10],\n",
       "        [ 3,  7, 11]],\n",
       "\n",
       "       [[12, 16, 20],\n",
       "        [13, 17, 21],\n",
       "        [14, 18, 22],\n",
       "        [15, 19, 23]]])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.transpose((0,2,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  1,  2,  3],\n",
       "        [12, 13, 14, 15]],\n",
       "\n",
       "       [[ 4,  5,  6,  7],\n",
       "        [16, 17, 18, 19]],\n",
       "\n",
       "       [[ 8,  9, 10, 11],\n",
       "        [20, 21, 22, 23]]])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.transpose((1,0,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0, 12],\n",
       "        [ 4, 16],\n",
       "        [ 8, 20]],\n",
       "\n",
       "       [[ 1, 13],\n",
       "        [ 5, 17],\n",
       "        [ 9, 21]],\n",
       "\n",
       "       [[ 2, 14],\n",
       "        [ 6, 18],\n",
       "        [10, 22]],\n",
       "\n",
       "       [[ 3, 15],\n",
       "        [ 7, 19],\n",
       "        [11, 23]]])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.transpose((2,1,0))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  1],\n",
       "        [ 2,  3],\n",
       "        [ 4,  5]],\n",
       "\n",
       "       [[ 6,  7],\n",
       "        [ 8,  9],\n",
       "        [10, 11]],\n",
       "\n",
       "       [[12, 13],\n",
       "        [14, 15],\n",
       "        [16, 17]],\n",
       "\n",
       "       [[18, 19],\n",
       "        [20, 21],\n",
       "        [22, 23]]])"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr = np.arange(24).reshape((4,3,2))\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X_46=\n",
      " [[[ 0.  1.  2.  3.]\n",
      "  [ 4.  5.  6.  7.]\n",
      "  [ 8.  9. 10. 11.]]\n",
      "\n",
      " [[12. 13. 14. 15.]\n",
      "  [16. 17. 18. 19.]\n",
      "  [20. 21. 22. 23.]]]\n",
      "Y_46=\n",
      " [[[ 0.  1.  2.  3.]\n",
      "  [12. 13. 14. 15.]]\n",
      "\n",
      " [[ 4.  5.  6.  7.]\n",
      "  [16. 17. 18. 19.]]\n",
      "\n",
      " [[ 8.  9. 10. 11.]\n",
      "  [20. 21. 22. 23.]]]\n",
      "Z_46=\n",
      " [[[ 0. 12.]\n",
      "  [ 4. 16.]\n",
      "  [ 8. 20.]]\n",
      "\n",
      " [[ 1. 13.]\n",
      "  [ 5. 17.]\n",
      "  [ 9. 21.]]\n",
      "\n",
      " [[ 2. 14.]\n",
      "  [ 6. 18.]\n",
      "  [10. 22.]]\n",
      "\n",
      " [[ 3. 15.]\n",
      "  [ 7. 19.]\n",
      "  [11. 23.]]]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "X_46 = np.empty((2,3,4))\n",
    "Y_46 = np.empty((3,2,4))\n",
    "Z_46 = np.empty((4,3,2))\n",
    "t = 0\n",
    "for i in range(2):\n",
    "    for j in range(3):\n",
    "        for k in range(4):\n",
    "            X_46[[i],[j],[k]] = t\n",
    "            Y_46[[j],[i],[k]] = t\n",
    "            Z_46[[k],[j],[i]] = t\n",
    "            t += 1\n",
    "print('X_46=\\n',X_46)\n",
    "print('Y_46=\\n',Y_46)\n",
    "print('Z_46=\\n',Z_46)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用数组进行面向数组编程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "xs\n",
      " [[-5.   -4.99 -4.98 ...  4.97  4.98  4.99]\n",
      " [-5.   -4.99 -4.98 ...  4.97  4.98  4.99]\n",
      " [-5.   -4.99 -4.98 ...  4.97  4.98  4.99]\n",
      " ...\n",
      " [-5.   -4.99 -4.98 ...  4.97  4.98  4.99]\n",
      " [-5.   -4.99 -4.98 ...  4.97  4.98  4.99]\n",
      " [-5.   -4.99 -4.98 ...  4.97  4.98  4.99]]\n",
      "ys\n",
      " [[-5.   -5.   -5.   ... -5.   -5.   -5.  ]\n",
      " [-4.99 -4.99 -4.99 ... -4.99 -4.99 -4.99]\n",
      " [-4.98 -4.98 -4.98 ... -4.98 -4.98 -4.98]\n",
      " ...\n",
      " [ 4.97  4.97  4.97 ...  4.97  4.97  4.97]\n",
      " [ 4.98  4.98  4.98 ...  4.98  4.98  4.98]\n",
      " [ 4.99  4.99  4.99 ...  4.99  4.99  4.99]]\n"
     ]
    }
   ],
   "source": [
    "points = np.arange(-5,5,0.01)\n",
    "xs,ys = np.meshgrid(points,points)\n",
    "print('xs\\n',xs)\n",
    "print('ys\\n',ys)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = np.sqrt(xs ** 2 + ys ** 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985,\n",
       "        7.06400028],\n",
       "       [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,\n",
       "        7.05692568],\n",
       "       [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,\n",
       "        7.04985815],\n",
       "       ...,\n",
       "       [7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603,\n",
       "        7.04279774],\n",
       "       [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354,\n",
       "        7.04985815],\n",
       "       [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815,\n",
       "        7.05692568]])"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<function matplotlib.pyplot.show(*args, **kw)>"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAASoAAAEQCAYAAAAH2znkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO29f9R/V1Xf+d75En7/NoIhiQLTiJPgCDSlWFxIgY4RKbGOaLBYtLiYWYMi2hlIdFqYLllDbYcljqPTDIhgQYgRSsqogGDq2IFAAhSEkBJIJCGR8O3wS2T48f3u+eNzT9zf/exf597zeZ775PnstZ51z91nnx/33Hten332PZ/PQ8yMnexkJztZs5x20B3YyU52spNMdqDayU52snrZgWonO9nJ6mUHqp3sZCerlx2odrKTnaxedqDayU52snrZgWonO9nJ6uUuB92BndSFiL4bwP9z0P2YI8xMB92HnRxe2YHqcMnTdxN+J0dRdku/QyJEdDqArx10P3ayk4OQHagOj3wvgP/7oDuxk50chOxAdXjkCQD+fcWQiL6biN5NRP+eiH5n8sa2Jvvd3k6OniwGFRF9hIieOKAvByJEdBMRPWWf2noEEX2AiL5ERM/vLH4XZv560fbPATyJmb8XwCcBXNTZVq90tbdwHPZdomeciH6LiH5pZr1bG4f9fK73QxYH05n5/BEdOQxCRDcB+Clm/qOZVbwQwFXM/OjOdr8TwEeq9sx8qzj9BoCTPe31yoz2Zo3DQckWn/FDNQ4HKbul3/7Kt6EDOEK+H8Dv9xYioodNZd+a2L2EiF4yo1+z2sP8cQAR7dub6n1oa/Y4HDUZsfS7w8Wc0v8jEX2IiL5MRK8iogcT0R9M7u0fEdEDRNlLiOgTU95HiegfiLzHCLf4d4nojc3FJqKHENHvEdFniejGzG2e+nXp1MbniOjVRHR3x/a/JKKriOjzk8v/9En/2wC+FcC/I6K/JKIXdpZ/F4C/C+DXpvLf3jHMD2Dmz6l2fpmI3izO/yURvbPFh4jovgBeA+DHmXnR20IiujcRnSCiM4XukUR0GxHdp6c9axy8MRNlbiKiFxHRhwB8WQMkeo6cPkTP1p621DP+aCJ6/1T2jQDM50i0Net5mK7pCqV7BRH9au81ExET0d8Q56csV6P5NI3Fp6d2rieiJ0fXuzVh5kV/AG4C8BSRfg+ABwM4C8DtAN4P4NEA7gbgXQBeLMo+A8BDsAHmjwL4MoAzAdwVm7jHzwI4HcAPYfNq/pcm22sB/LPJ7uHYxEW+L+njnwE4B8ADAfwHAL9k9P90ADcA+IWp7icB+BKAR2hbp52s/FXYLB298o8F8GEAdxW6BwN4gWH7TQA+D+BRAP67qdz9pry7APi/sIkbVe7hSwC8JLH5CIAfEOdvBfAzM9u7YxyyMRPj/sHp/t3DqM98jpy23WfLa6vdd1H256ayPwzg663syOcBG2/rrwDcdzo/BuA2AI+rXDNOfa4ZwN8Qeb8lrtedTwAeAeBmAA+ZbB8K4L9Yyow5f9tY+v1vzPwZZv40Nq/Tr2bmDzDzVwG8GRtoAQCY+XeZ+VZmPsnMbwTwcWwm6+Owefh/lZm/zsxvAvDeqdjfAvDNzPzPmflrzPxJAP8ngIuTfv0aM9/MzP8vgJcCeKZh8zgA9wbwsqnud2EzIS1bS5aW//8AfA6bT9omPwBjKcXM/xnArwB4LYBLATyVmb8wZT8TwN8G8M+mT/MfLbYfyfsAPAYAiOgJAM4D8K8HtFcds1+d7t9XdAXBc+S15z1bWVuPwwY+vzKVvQKbcVl6bXuEmf8cmw/5H5xUTwLwV8z8nhnXHEk0n05g42CcR0SnM/NNzPyJGW0slm2swT8j0l8xzu/dTojoHwH4eWxIjSnvDAD3APBpnjA+yc3T8dsAPISIPi/yjiHfY3SzSP85Np9GWh4C4GZmPqlsz0rqHlKemT9ERK/F5q3Z2yb1ucz8m06RDwB4MYB/yMx3XB8z/zaA347aIqK3Avie6fTuk+4F0/mfMvPTVJH3YeNVAMAvA/inPC3xKu0FUh2zm+FI8Bx57XnPVtaWVfbPvX5h+fP0emyg9loAPzadA+i+5kjc+cTMN0zPxEsAnE9EbwPw83zqy5N9kQMLphPRt2FD7p8G8E3MfH9slmeEjYt7FhHJr4ucMx1vBnAjM99f/N2HmZ+aNHmOSH8rAGuwbwVwDhGdpmw/PaWzH5jPylfkSgBPo43cHRv3f4/Q5k3gb2ATF/rHHfUDAJj5aW38ALwMm0/9Np4aUsDkURHRf4PNB8nv9LbpSHXMzLFPniNLomcrbMsp+62OLbD8efhdAE8korMB/ANMoJpxzX8F4J7i/FtEOpxPzPx6Zv4ebIDGAP5Fse9D5SDf+t0Lmwv/LAAQ0U8CeOSU925s3M6fnoKZF+Gv3dr3AvjiFOS7BxEdmwK7fytp73lEdDYRPRCbmMEbDZursVnrv5CITqfN3pm/D+ANU/5nsFnDe5KVT4WZb8fm4fmb2Hgw79I2RHQWgH+HTWzqvwfwnbT9vWz/EZsH/H8FcInyEpbI0jGLniNLomcrk3djs/3i+VPZH0rKLro2Zv4sNnGsV2MDk+umrN5r/iCAH5vmyoXYfMuhiTufaLPP60lEdDdswhJfwWbs9l0ODFTM/FFsHvp3YwOA78QmyI1pSfFDAJ6DTcD4Wdis7b/KzCewudmPAnAjgOMAXgngfkmTrwfwdmwChZ/EJjCv+/Q1AE/H5hX7cQC/DuAfMfPHJpP/BcD/NL3B+R9mlK/KW6Z6HofN+NwhtHm79vsAXs7MVzLzXwH4l9jE3bYmU4zxwwBuYuY/GFjvojGLnqOgPfPZKvb1hwD8BDaxxB8F8KbEfunz8HpsPrDuWPb1XjM2Lw7+PjbX+w8B/FtRVzSf7oaNt30cwF8AeBA2H/L7LnTqcnu9QkRXA/g/mPnVM8rehGUbNfdViOgRAK4AcCUz/+JB9wcAiOiu2LzB+pEW0L2zyJJnayf7I6vd8ElE30tE3zK52M8G8F8B+MOD7td+CDNfj83bpWsPui9CXgzgP9wZIHWUn63DKmv+PapHALgcm7cZnwDww8x828F2aV/l17FZqh6oENFjAPwxgA9hE9C9M8hRf7YOnRyapd9OdrKToytbW/oR0YXTlvsbiOiSbbWzk53s5M4vW/GoiOgYgP8E4O8BuAWbPTjPnN5W7GQnO9lJl2zLo3osgBuY+ZPTK9o3YPu/ibSTnezkkMi0R+uD4u+L4psRe2RbwfSzcOrXEG7B5rtgsqPPBfBcALjXve71N7/jO74DAKA9PMvjy2wqdVTrHq3P8ir5VZsRZfZDTt3oPbZMZDcyz7NfYpuVrdQtz6+99trjzPzNZuNFufDCC/n48eOp3bXXXvs2Zr7Qy5/ebD9q6uMxbHbrv9mz3xaorDtxyixh5ssAXAYAF1xwAV999dV7vjF98uTJO45TGTM/+vPKVv9a+agOK0/r2rmuT9pVdNEx0zWRfcikF2490DnttFMdemsSRrrKMdK1Pnj28s/SWeVafXP+estLW6usPj927Fj0vcSSHD9+HNdcc01qR0Q93zt8MoBP8OaL2KZsC1S34NTvT50N+7t1d0gPpCqAssp65az2I8h59pGtBTwrHekqR5mOgGQBaITHZdXhffJ7/TvttNPAzCCiO+pr6TlHmW59bPrWhwZNaadtLZ0G6cmTJ/fU1fMn+6NBruXkyZOnAEm23fKzOubIiOdEycVIvju6LVC9D8C5tPnFx09PHfkxz7gKqSqgTpw4YdZb/ZPtZvV4+U1fBdQISHkT34KYd+7p5ogEg6ezlir6Ojxw6WMVVjodASuDlpWn6+oVWYf0jjyRwNoPWBU98jOISLpel/FmFXWK0OYbD0/H5qeKXNkKqJj5G0T009j8VMkxAL/JzOFPri6FVLZMnAOpHjDpPG/JKM+ztD5qHbD3ofGg1AurSp4lemLrPA0t69zyUqRocHkQknVl6QqwNKCiPMvD6RFdvsEoglaz3yas5HOYyHFmvqBg9/0A3s/Mn4mMtrYznZl/Hx2/8z0XUjKvB1K6TgDdkLNsRwAqglQFTHMB1QslS6w6PM+qnWtoSL220eCyoNXrUcm2M68ogpNlI+upLP1kex7sIvBEsBolI54TIc9E4SeDVvMVGgtSVUB5kJoby6pCKQOdLhOdW2k5DlIsGy8vSlvnmb5Hqku/alp7SRG05nhU+twDjR4nCzh6HKpejfacIlh53pUHq1EyClREdE9s9lr+t5ntKkDVAwwLPlW4zYVUBq4lgIog5b0hjI6ZTqcjXSVPi7f0q3hVVUhVoTXXo9LnGhY6rzouveCQ0PLKZvptwGoUqHjzE0XfVLFdBaiAvd6IByQPNL2AWgIpXd6rQ+uj85aeA6c5sLLOPV2PWOWtWJS0XQKpDFqel1UBlJYsSK4BZv1ZHloVJGuB1ShQ9chqQAVsF1JzY1keWHq2Lmiddd6zv6pyzHTeeaavSuRZeecVSMm6vXiUBIYFrNanDFAaPK3NKO5UHRsvUJ6BqxdW7RpGxaj0h+l+yWpANQdSPXBaCimvvFeXpdc6YC+gqpDqBVMGqG0/fHLZBNS8Kg9OGkhN78FKX5/c5JkBSooG18i3elKi+FPLr8Kq6aoQrcjSD7E5sjpQjYCUl39QWxe0Hjh1qSvzrXSkk8dMJ9uN7sNIsUChpXk7zd6ClAaQBatIJ/ujPSJpV/Gqorqqf1GgvEkWMAeAY8eO7dFbbypHypEFVRVAmU2W19paGnCX6R5oAX2A6oGUBSgPDvpBsx68pQ+j9pi0Xqa9fVLNJoOUhEmki5aFVTjpvLneVSVQrm2trxydOHEihdUuRjVQKuBZAqkeMEWQ6gGT1HuA6gFTBicLTPKh8tLWeTVPiheXknkaQLqcFU+JNnhGYGrtRWkJCqnT15/FoZYuBSU0e5Z8chx1n636l4p8DvdTVgOqucu5NUAqgtYcQPVAKttjVU1HuqpYZS3PylrWWel29PZKVWAVpaXoN3oVOGmbylIwApkub0kUh8p0o2QXTHcAEwHDA1H1+35LAu6RTbR1QevkeZYGcjj1wMo693Q94gFK6jJgWeDKoNXqt6AkbeS51EWgsMDkXXsWKPegJWEVxacqYFp6Dz3ZVr2RrAJUGUgA2+OaA6mK55b1KQOXVYdVp9R59rpOPWbSTpfx8nQ60kV6LdnST0OrB1IWkDxoeeCqnkeeUVV6Yk8aSLLsnDd8TbYBFPnc7aesAlTAqZO0waQXUidPnnRBUw3UW2Wrf5Wge6bT6bn7qzJd9bxHrLKWF6XPeyGlj9byMPKovHOti2Cj7by/6hJMB8wrsLLGW+/PWvNXaHpklaDKoLEtSM0FFBB/obmil2kPTpZ9dMx03nmmr0gWm9LncyGlYWPFeXqApb2mEd6VLl/d0JnByguuS/02oLIDlQGpKkAsUFSWedvYWxXVZ+XJa5XjIW2tdOXo6SrnUioBVG/ZkUFrKaRa3Z6XVQWW7PsS78gSDZ0IWD2w0vdM2+5ANVDkpM2C4BZ8rDKVN4HbgFQvnCxAjYKUBSudHvkGpwdmoyAloWKBqwIsrfO8pci70n9RoFx/dSaLQclyHpiktGvJ3iDOEf287pesAlRAHNeJ/nogtfRNYlY267vVz+z627ll03ME6htAM30mlYkupbIzvR2rsNJpb+Ja0LLyer0rGSj3Yk/Stgor3f/WT+u8lelZplZk7nOxRFYFKg2I7Nyb/HMgtWSJWQXTHEBVIVUFk8z3HnDv/kSivRMrT4OnpT14tXwNpKb3vCgvbQEr8qqiCd67FJTekwcry7uqwCoCnwT+KDnSoJqzDOuBiweaniD6NrYu6Pqi85b2dBGYPEBZD92cB9EqU41NSduW9rYeWACSgPHS0t4DVgQmC2K6jt63e9UAuQUrK67mnY9++3dkQRV5Hz2QynRzg/S9gLJsZR1WvtbJ8yit4RSBKQLUKGAB4zZ7tnMPWpXlX2sziknpiexBKbre1scsTtWkwaYSILfGMrt/2n5kXOnIggrIIaCBsy1IWcvNSv+i+qJr1ProvKWBvl//zHTeeTUP2M5mzwq0Kss/z6OS4i0HqxIt5yrQymJWmY0FW5keFafSz/R+yapAVfFyquDohZQHukpbPX316ovsZN/lePUcPV3lvHr/tPQu/TxIZdDyvKyqR6Xr9N6iWX/ejnItPVsSrHNrjDM4eeWWyuj6KrIqUM2FVOYhtTJLIdUbcM+uy8rXOiD+cb2eo6ezzj1dReYu/ayYlTx6Sz0LWK2tCFDW9fbGrvTbvQhWzb6al4FJt+XBaRejGig9kKpsH6iUicAFjP8d9h59a1+Pj5X2dDpf63TaOq/mLV36Vb0rTwf4v+LZ+pR5VTIvA04mc2Cl28y8qpbfjnPva6/sQBVAxLJZArYe72oEpHqg5QXerXSkk8dqWra/VKzNnfq8B1IWrFp9HmQyQGVieVc9WxKAvb/C2fK8OJTnJXnn7Xq9Dwsr+D5X5LO2n7IKUFUA0AOLDBhLIdUTcK9cX7OpAGoOpDwoVYA056G0PBwpeod4D6QsWFnelWxfA0sDSudlsStruefBi8j+Fc5WTwaratBcwyj6IFoqo+ojovsDeCWARwJgAP+Ymd9t2a4CVEAMlSw/sp8Lnx64Rf2rwCuKaUldlo6OHjT0Qxc9hF6eNfG9PBkDkmLtlfKOrY1q4FwCS/bRA5d3jdlyzgNWL6xa36wlXcu30pV41QgZ+NbvFQD+kJl/mIjuCuCenuGqQNWOIyFQAU7PdoWl/asAqnou9VoH+HusonSky+6dliw2JfU6vpTBygOXd24FybNr0h5TJW7lASuClQcia0mn7fX4VuJVS2VEfUR0XwBPAPATU51fA/A1z35VoNKT0dL3QCg7j0BU8bCAesBdX0t164LUZenWHz2u1lGnrXNPF0klTuIt95roa9D7pSxYVYDV/qz4lbfsk32S5QE79qTt9Vu63n/GYJWJPnCyeNVS0fMzkDOI6BpxfhkzXybOHw7gswBeTUTfBeBaAD/LzF+2KlstqHqD2nPf0M2FVG9bFqCs67b00Tlgw8l6mOfCKsuLJoUERju3IOWBS3tCMs9KR0tAqbeWgz3SAJL9xpS1pcCCVXQfqvEna4ytupdKsb7jzHxBkH8XAI8B8DPMfDURvQLAJQD+qWd84BJN5t7JX4VLL6QqQfol/bT0WifPgf79VZ7OOl8ah7BiJT2Q0kdreViNUUmdteT0YlcZxGT5nu0IGiSWTZRfgVb05nCpDKrvFgC3MPPV0/kV2IDKlFWACjg1+C3P507+OXGnpZCqBNwr16ZtrPHR9UkbL0+XA3Ig9T6UDQRRvfpnXdrRg5SGj+URRcDyvCoNQB27st7uWcs5CSsPcBmYtI0Ftyz+pD8UvGD8UhlRHzP/BRHdTESPYObrATwZwEc9+9WBSqYrf732vWCLIFVZAlYA5+VLfcV7yiBVefOXPYRWfmXpJ8+tGFQGKQkXmc6AJfvlgUv2q/cXEKyy0baDSKfHTt+XLP5UsV8q+llcKD8D4HW0eeP3SQA/6RmuClTbjkv1BsA9SPWU12V7wRsBqgKpuW/+MmBltlZsqp1by68mEbR0+QhYOr8yWXtgBcS/MTUHVhmoWh8r99CzHyGj6mPmDwKI4lh3yGpAFe0lWgqBbOnmvQ1cCqkqjDwb3b4uZ+XpsZR6fYzSkS4SDaimsyaOhpDuuwWtKB0t4+T1WMu5qI4sXtVgU4GVHs8ozuXdm554VS98KzIafBVZDaiAscHzpfa6TPVN4NyAu25Lnuv6rLzozZ/1AEeAGuXaW1+h8dJSZ8W5en4hQcdnNIgqYkEnApYHKz221vmo+JM1trL+UbJKUBHROQBeC+BbAJzEZj/EK4jogQDeCOChAG4C8CPM/LmpzKUAngPgBIDnM/PbojasyejpIn0FAh5g5kJK5o18K1gZD6D///7JdPTwLn0Yo8mhg+ltMnlH7eVImGlgSZ21HJxzDXqPkwcsC1ZWee8rMEviTxpOVv2jZJWgAvANAP+Emd9PRPcBcC0RvQObHaXvZOaXEdEl2LxafBERnQfgYgDnA3gIgD8iom9n5hNRI1XYLI1jVTyjSn+seq1y1SWgV97TVWNX8miBQz901kPY82B6Sz+ZnhNM116WBlZrU0PLW8pV/qLd6N5yyoJVNMayniXxpyx/FKjks7qfkoKKmW8DcNuU/hIRXQfgLAAXAXjiZPYaAFcBeNGkfwMzfxXAjUR0A4DHAjC/bCjaCSdnD0Tm2ltte/GrqJ0emGbLPA9QHpgyOFkPdAVWXp6eABagoolTCaa3OqxYVuUXEvRysCrNY+mFlbxGL8hv2es6K6CKloBe+aUysq6qdMWoiOihAB4N4GoAD54gBma+jYgeNJmdBeA9otgtk07X9VwAzwWAM888M52klpewFFKZt9UDqV5Pr9JHmdcDqFHB9MoDadl4XpUGloZRBC3LuwLqv5Ag65+7FJzzJs9a0kVB8554VbvebAmoPbWlsmpQEdG9AfwegBcw8xcDV9LK2HNlvPnez2UAcP7553M2WXtB0Mr1QKPXphdSXsA96mv0NlTX4cWroqNOj3brvYC65121Y29cyotHaXhVloKVN3yZzoO0la/TUbwqA1GkGyWrBRURnY4NpF7HzG+a1J8hojN5402dCeD2SX8LgHNE8bMB3Jq1EU3CyPOw9HPiWLqeaiyrGmivXIu+LsvWOre8LWkndTLtQSl7EDVgPPEC6tVguo5LtbIesDwIRX3z4kwRsCqwqgbRvbQXr/JstRfm1bNU5DO1n1J560cAXgXgOmZ+uci6EsCzAbxsOr5F6F9PRC/HJph+LoD3Rm1k4Gk6K28uCHqAo6GTlYn0c67BKlN526fHLgum6wewCiwtVmxK5lWC6a28BpcGkbTrjUdldpU3fNF46POe+JO0z4Lmesys46hguu7DfknFo3o8gB8H8GEi+uCk+wVsAHU5ET0HwKcAPAMAmPkjRHQ5Nt/b+QaA53Hyxq/JUvBE9YyA2khIabuWV4lbefEq6yHN4lVROtJZUo1NSdtqXKrVGwFLS/VtXwa17A1fkwxUPfEnaV9dAkZgGwmXtb71+1PYcSdg80VCq8xLAby0pyO94LH024pj6djSHEjNhabUVQClYabtraNOW+fVeyglglSDjgSRBS1rKaiBFW3srHpXrV3vN6YqsKqAK4KPTFuxPJnvjWsWWB8hI+uqymp2pnveQAUuQP51kx54zIktbQNSOt+7ds+u5yjHcLT0bvBsdjpAroGl++3BqGcp2H5jqrrc03Xr8fQ2d0Zw8uqJPCULbF57S0Q+d/spqwJVNHktmwxgc8EwAlInTpwotVGF1BxAZXDKYlaRzhJrCRbFpGQZvdSTUIqAlQXS9RJP5lswstqLxqJBxFrSaXsPYhac9PhknpK0P3nyJI4dO2bWO0J2oDImopWnbSQoorrmQMoqvxRSJ0/W/lOOzLdsLU/LSstxssZdHrW+9x428QLqWTC9GpfS7VZjTjK/TX4NragtL4huLen0mOjxiYBiAaiik6CXNkchmL518T7pK/DqBU+PrQei6M+DlPXWsAop6xoykFnjaY11lLbOK6KXGl4QvR2zuJQFImmrJ2EPrJro8wyM1nlbOvb8vrmV70Ep24Igy3m2I+TIggrwJ1kGl8hG6+Ys+XrzrfpHQqoKqCXBdOtBrMSvrM2d+lxOqJ64lExbnpPOi5aC3nf4qrCKguYefKxx0HVF90WPQ3TUgfrRMapVvvXbL/E8hQhQPeCxbKOylv0ccEWQmgMwz6bpo+VgdJTjOVe88hom2VEDQuq9Nnu9pwasKqyqSzpdhwcdXb+1BLQ8Kx1Yj4LoXtxsqYyuryKrAlXkIehjxbYKpQqkKmWqkLLiXFF7cwLq3ljJYyWY3vtQesswKdVfS+gNpPe+9WsAqsAqGhcPbtbbTl1WQ0bm67JWYD2zlW2MkiMNKiDeyBhBILLV9UZ2c6B2UJCKABVBSkPDmzxasodTT5ymkxOoiQWuKIheDaRHb/0s70lKBqtouafP9XVY+Xp8tKdklbVglNluw6s60qCyAKH18ijL9YInKlcNnje7HtBEkOoFGJB/F1DWbY1zRdd7/5pYb55k2otLSfC0ekcE0j3vSdtEMPKWdPpcQ8LL11CXnlIEo8zW86pGyZEG1VxvyoOaZVupt0kVVpFtBUSeN1at17suOaaWrTx6Ol1HRbxfS5DpOXEpC1hzN3h6ebpctKTzoKavt7IErHhIlZiUd4zGolf0PNkvWQWoqgPufYotAY/Ms+y8shFMTp48uW+Qsvo6J17V+pPdI09k/MSSalxK1hEF0rOl3hxYWRDSMLfgI+08e70UjDwlK7Ce2Va8qlGSPQvbkFWAqok3OfVEzWxaXVGdOq+65LPK9yzbKpCqAsy6Bmss5bkcmyyY3vNAStssoJ79WkKTLJBeBRJgf4fPKleBkbf00uMQQcnLq3qgvceRXtAoUBHRTQC+hM3/VvgGB/8CfjWgyj5B9OBEdhEsLF11ydfyM6jpflRB5NU3IqDuwSmaYNa4Z6LfYEUxKaD/Vzy9NrOloN6IKeu2guYaRsBeGFfHruIpaahYmzWtMtEbQA3AUTIKVJP8XWY+nhmtBlSAD53KZPZgEdUXwWsJNKJy24JUD6CyCaDT1rkWa2nTzrWX0I4WtKyYVLOXE7jXs+qBlYaHNQYVr0uDwsvTR2vsRhxHiHym9lNWA6oKcKRtdKy8MctsvfK6vQpUsqVgL/R0nVFfLTtpr8dXpucuF7zgcRSXsmJOsk9WwN0SmW/90oEFKw05PQZZvMryuqzr9wLrFriWeFVR4H2EFOs6g4iuEeeX8ebnx0+pCsDbiYgB/Gsj/w5ZFaiiYzTheo8RkCIbDxy6fx5QrFiWVV/lS81RvjdeEaSWBNKlePGQKJiu01aQ3GojWwq2OnSehpUOosvr7fGcslhUa8tbqlneTwQe7+j1YZQUP8COcxBzmuTxzHwrbf4xzDuI6GPM/CeW4WpABcRQ0edzJ7Fnm5WpemlV/bYgFV2TPAf8eJVOR7om3jrQ6xcAACAASURBVNKvpb24VCtjLfmsJZle6rX6vN+JaunKTnPPQ4o8JwtkGbAsuFi2kVc1B2qjZBT4mPnW6Xg7Eb0Zm3+rt25QeZMaGOtNyaPVXjSxvT5Gcake2ESQqgLMG0MPUNnYVEXaesu9dm7FpSSEpHjLQdlWBCTLG2r19sSlPL0FMg9Ksk+ZbQYgC2rZVoURItteIkR0LwCn8eZ/hd4LwH8N4J979qsAVQYF71gFQAaRrP45we5Mr+uMfh5mREC9J5iuH8Tqg1mZfB60PM9J2vX8xlSzjZaBvXEp+UZQj1XkGVXGwztWAGQtJQ+BR/VgAG+e+nUXAK9n5j/0jFcBKiCGlLbpBVpPnVYbUfuWfk5Q3bOfA6kIUNXxWbrvRsekgL1v/CSQIs9JTlpp43lPrf8aVlGsS97PTB8tATVUpI229WJVFnA8vQc1r44RMqIuZv4kgO+q2q8KVNZRex6Rrawr+os8JF2vZRvledCJ9N6WhQh4FehpmyjtgWnOQ6mXd0BfXKrZy3iUrlt6Tw1aGlYaMtaP2lXjUt4yLoPKHC8qApC19MvqkGM9QkZCryqrARVQi5eMBpo+aiBIvUx7eXPiVVUQNdslAXVr3PR4ROlIrKVfO1biUhpYvb8xpWGlbXrjTxZ4ZFsWjCRUZDkLYJ5X1QszDSLPZoTI52s/ZTWgsm5oJYiub0IFaBW7DGJW3tx4VaaXMFuyFNTjGl2vHKte8X4oD7BjRhpYlp30nGR+Bis9QXviUlY91rLPgkyznQse3Q9rPC1YRTGtUTKyrqqsBlTA3omvdTJP2kTw8SZr9hdNeC/ParsXUtHbvV6A6fMsXmWBqfehzJZ9EkoRsOSfjj1JaGWwkvXL/lXiUhKw1lhpz1DCItusmXlA+ijrzGDlHUfJkQaVBakorwdkFaD1HK12MnjN1VvLPb1cXBJQ11CxrrXqWVmeh7Xs00Dy3so18ZaC3hJP9qESf5J6awyst33Z0k2mPajIuquQqQLJyhslRxpUgD05PEhoXTvvgU42sb08qx3LPvKmsrq9euZCKgKUNTGz+yOlTQ6rnFyqaShZwLK8KytQ3sSClX7jZz07nr4CpcoSLlqCRQCS1x7VGdXrtT1KjjSoNEC0zsvzJqJ1lHY9QNN16Hq8N4PaLoOXVW8VUlGerNfzriqelSfSxoszAaduPfCWfZZ3JZd7VVjJPmX6HijJOjKvynqGqlDLABfZeG2NEP0M7ZesAlTRpJgLMAtoPTDSIPGA5Hkm24KXzov6FPUz6nurd4no7QgRhLTOA5Is0/M7Upm+B0oVLykDkOxvD4j0tUb1WHmjZBT0emQVoALqS7yKTgOsxzYCWlRHBIqWtpaNXh1ev5ZAKoJWq8+7L945gD2TIItLaThpkETeU5MsiJ7FpXqgJOvwbCtxKS9OFZWN4BdBSkNypBxpUAG59xN96kdwiYLoFsws2yhmFrUfAUQDqKqXYxTlWcCMdNn4VSTypFq+BazM4xrxO1IRaKy3fbpc1auyIJZBK6o3AlJFZz3fS+RIg8qaIBWdBbC5eV5cxwNb1aPJ4KXt5y4FI9sMWtY4WPfHEx17AvLln+U5WZ4U0ZjfkYqgJNMSSh7AoiVZD2wywOg82VbUju7TKBkNvaqsBlSAPRkiWEV21oBWAaZtlnhTunwFfpneglIPpKzrqQbTtZ0FA8s2WtbNhZUOosu+Rss37x71AEzX43lEcjznwspqv41DVIe2GyVHHlTAXijItP7EnGMXQUrmV+BThYxVbw+8In0EKb15tBJQ1/3LxLPL4lKyrLX082BlfUhEcSnr+ZDxLAsovUs9C369caV2LzzYjdCNkqUvWubIakCVAScDTVXntZHFaWSdUT1evV6/KqDL4lX6/OTJvd8VnBNQt67TEzkRqnEpaeude0Fz3S8rpiTtrWCz5RVFsaoeqEVAymC3Ld0I0c//fkn5vxIS0TEi+gARvXU6fyARvYOIPj4dHyBsLyWiG4joeiL6vmobVVj1lLHyIrhEoIngo9uqAsm6Bq8tqw4dOO+BVEufOHHijnIajidOnDgl3/trdhqsrU+tDqnTNt55ttSN9Lqu6P57z5F1D7x7aD1Lut6onFdHNh8qz/4oscbeGt+R0vPvU38WwHXi/BIA72TmcwG8czoHEZ0H4GIA5wO4EMCvE9HeVzZKMrhYdtlNXqqrwg2wf72hCiRrcldBZ4HHytOw8Mo2OFnAqzycElyyTqsP1rkFGD2+3nhbdt4YWnVUARQ9Q56N9YFnle8NaWR928YybbWgIqKzAfwAgFcK9UUAXjOlXwPgB4X+Dcz8VWa+EcAN2PwWcirbvEkj7KwHUt+YCtCqdVbglcWk2lFPFAsQnjcmy3h/Hmh0G03vAcOrIytnjY22rdwfr7x3L6P72wu5Xl0lP9LNldWCCsCvAHghAInnBzPzbQAwHR806c8CcLOwu2XSnSJE9FwiuoaIrvnCF76wp8FRN8vTVR4iC2C9S8HKRIo+2bW95Ul4ALNg5p17yz65vPOup42BXALq+uYu9WSeVa4XStZEimDTjlmd0f3XMspuTv5Skfcz+hstKaiI6GkAbmfma4t1Wq8X9owUM1/GzBcw8wX3u9/9tnpTsjLyfO6DaD3slQlg9TMCmrT1Jne2FGzHBhSZb8WrLNhovReX0rbe0k+OmQUrL20B1Bo7zzZaKmb32rp30f0cpfPazWxHiR5b62+0VN76PR7A04noqQDuDuC+RPRvAHyGiM5k5tuI6EwAt0/2twA4R5Q/G8CtPZ3qGfylNzxabnrttPMMNJZOT6QsTuJNQA9GctJHyzjPy9LX1vvp2PN1GXnebGSelZblWzutr3O3Fchrjt7qWbqTJ/fuPLd0bYz111qsNiI7mW52Xr6UkfDYJgQ9ST0qZr6Umc9m5odiEyR/FzM/C8CVAJ49mT0bwFum9JUALiaiuxHRwwCcC+C9SRuhbs4nSTXu5OVbAKvoNASstiqQ08co9mG1OwdS0i5a7llelOyn9pyaXttZ59W0d20W1PV4V8Z2zn3t0VXyozKV/G0BRY+r9TdaluyjehmAy4noOQA+BeAZAMDMHyGiywF8FMA3ADyPmU9UK50DIJ2O8uc8NCN0vUtBb+LpcpUlUgapymT0Hr6m116Bt4FTn1u/G6W9ktaOtz9K9iXzqixvbL/2OelxizZmjspvY2V9V3KubAuAkXSBipmvAnDVlP7PAJ7s2L0UwEt76l4KIJnuybfq3U+AeVCReZ43FS3/Mkh5u9Y94EXjFi2tejZ0euCyln0SZtJG9nXuUk/KKF0PZKrl59ouEflcjJBp69I1AD7NzE/z7Hr2UW1dsgHIANRTrqeuKizn6Nq5pbOOmRcmge+BLIJUO5dLQAt41rllK/ttneu8nmWfN5bZuFsfitnyr1I202m9lV991ioyt1wm8n57fx2i92easipQSakMcs9NtWy9h8nSRfEpqe/VeRPD6r/U9yz/PI9M5lkxJ+8hjACl0x7AWpvWGGVQ0hMhGr9oKet9GGS6Sn5UplK+B2jbApIn8hnx/iri7M80ZTXf9Wsy9wZkAOlpI1uGznn4enWeh+GV1/kevLxlofew6QfPGk9vyWdJFJey0tZSz8rX7bdj67MXL5qji9royc/q92z1eFbf/I2SIojOIKJrxPllzHyZsmn7M++TVbY6UAF9UOoB20jbnvKZTuujsrpdC0jV2JVsvwIs3Zdq4FhLFqPSr96tNrx8rz8jdPp+REHyEbZz4bVNYFnPqyPHmfkCL5PE/kwiemJW2WqXfk3koGSeUqWOuRCc00YP4CrLFmkbeVNWO1bsKvOoJNTa0YtVeUtCqw19DV5at++NpReXi8axV2fdB2ucI+n5oOwtl9XRGTdK+1P5cEuk7c+8CcAbADyJNvszTVkVqEZCorc+L7/n4bQehp5AawSzysSy4KS9Ip3WQPJiUpXYkwemCqys67BiUV58Sl+bN46V/KiM1S+t248Pxv2qz2tjKajY359pyiqXflpGgGhEfZVP2qWTJMqv6DJvy4NX5cHTRx1XypYjOh3ti2L2l3qWzmpv6XIry89svfhR1O+ovz392KaM9M6qsjpQjf4U6PlU9GRbn5Ze+aje7NNc6yygtfM5f1Y/9YRpf9YP3OlyVqwpg1amywLMlUm+FFiebBM8+wGyqsfUWedVmPZnerKqpZ+W0Z5UpZ1tuvAZrKx+eF5Uz6t4mV8FUrQEjLYlzPHMpFelZYku+2Cae6+9NkY/oyP6tw3p/UAbIavzqJbIQYBtbn0VOFr5PfW2sp4nJI9zPKpW1vu09iArj9FST25F2ObWAD1e23rdv01vaj/lIEC5Go/qID4xtgm2zFOq1J31qccbs7ytOX+Zl9XrRbXy3nVL6fGKLNnmPa60s03Z5gez1dbOo1Ky1odhdF8qD1p1yeP1IwJcBDArAA/s/SJype5sU2aPR1PxPno8FK89r0/blLV6X9YHy37I6kHVK2ta11f6MqJfWX0ePCIvp/Jp6cEDsHeryzI9k2wuKDzbg57sa+1LVQ5iLt3pQFWR/XSTe6TSfk8f53pbFWA1sd7u9UBq7kTdZixpiVTgeNjlIObJamJUa5PKMu+gJVsWapssv7IkzHacW55apR9r8oQ98cZ7TX3cD8k87m2Mx5H0qEbJYXtAK55kxdvSHlUWP1pTjKUih6GPBym7pd9ODrXsJvWdX7blMWWyA9UCkV8BOWyiv/5ipT1bqbeO1fRa5TD08SBl99bvEMha4dT+g4uWDEKZrTxGQMpg5bUn+2/pDxoaXl9kf4+a7DyqA5DIW1gjkLz+LqlDAsnStXbaD9Tp9hvE9J+2ke1b6R5ZE9gOuv39lh2oBku0vFljX+bC0avP8rJ6vSZrrHSfMzhVvS3vvnhQysSzPQiwVPpyGGQXo+oUb+J7S6DD1JdouVGtz4KXBpK350l6UXoiWW/DejyqbAnZA6XRk7yyzNsmWA5LjO9Ig6onuLvf7Vs2c+uWsFkSP2rS6uvRWbCS9epy1h4ZDzzt51miP68tea0VXetfJNuc/AftJR0U2I40qEZLBXxLwGO147Wf9S+DVyVQ3qOzlnqRF1W51jlwkl6UpZP1ezqrvmraktGxr8PiJfXI7q1fIB4cRntfcz0e3dcqvLw2vPiS7mekax6O1mVLPM+jsYLu+tj7J8tr72iOZ+Vdh+V5jYDSNr20Nb0waLKLUU0yGjwVEGTtVOCVTaq5oKt4SK1/li6DltVXa7lnwU2Ws2DlLQOlvQenzNuKriGLKY2G0txyo+GzXx7bDlQFGe1Nza2vx/PygOZN/AgGnoek7TJoWX2JxOqX1b853pSEWutvBjRPF12Pd409MOuxHfG2cr/g0yMHAapV7VobcVNG3+Seh3RUXCXzEnR7GmQyraEg8yvez2mnnXZHnkxbeb2QqnhTUf4oXU++1R/d1+z5Oog42EixvG3rhctIWb1HJb2DUW/M5sSPemyzfP0GrkfX4zV5+VZ8q9l4D12ztbwq7R3JtAdCDbweeHlAWworq545Hz5W/6tpS0aAaNROeubdD+fdIRl4PNteeHl1VG2z/lZtta5NYK1rx2z5Z0EJgJuORNbtLf10/yreVJbuXQpmtlH5HphFOk/m2u43zKoywmMiorsD+BMAd8OGQ1cw84s9+9WBqgKeqsfSW85KR/mRTpbXbUV2URtZgLwaLJeT1YNVa9MKontQt4BjQcqDkAZKFU4ZaKwx0G1EdhVddcyz8r3lDuLN4KCl3VcBPImZ/5KITgfwp0T0B8z8Hst4VTEqT7JP8Uo5b6Ja+UuWAJ6u8oluxY+svlh91BNbx6qstPRcWrzJikPJo7TV514sS/bt2LFjd/QhApa8Tn2NVjlrrCLoVSEzB0ZL8/UYZLbbhJIlI2JUvJG/nE5Pn/7cgqsC1X58Ao3K36bO0utJakEJQAlQFqzkuYaNBzPPxqvj2LFjLmCitLyu3nHLYlqWzhrLis5qo1J+6fNZsR0Js1HBdCI6RkQfBHA7gHcw89We7WpANTpAudR2pC4CU/RpH00ire+Z+BmsPI/K8pQioFlQ0ucWeKO0Ba+eMV16vzKd18bI/KW2S6QCqQlUZxDRNeLvuUZdJ5j5UQDOBvBYInqk1+6hjFFVbCt16RvadF75TGeV9drVMSc5+aI4U5usMrZUeUit+ls/svNWNopNWekosG1BqhK70uNu1VsBmS4/AlKZLhuvbcNslBTf+h1n5gsqhsz8eSK6CsCFAP7Msil5VER0fyK6gog+RkTXEdF3E9EDiegdRPTx6fgAYX8pEd1ARNcT0fcV6g91+uGP8vVD6uVnumx54E0GS9cmpdeWpbcmuG5b1zt3qafPWxzJ8568eJbsa1vmybKt3rmQimJT1XGtAi26X9vSjcyXYsW7lsiIpR8RfTMR3X9K3wPAUwB8zLOvXsErAPwhM38HgO8CcB2ASwC8k5nPBfDO6RxEdB6AiwGcjw0hf52IjhXb2SNzPlF6bnIGvh6dfPi9NuUkqULJsu0BVAOKrNM6tya/hJb1wMu8Y8eOnQIjq95WxjvvjV3psbfso7H27pN3X7z7kOl6ntPqMznnw3iEDIpRnQngj4noQwDeh02M6q2ecbr0I6L7AngCgJ+YOvk1AF8joosAPHEyew2AqwC8CMBFAN7AzF8FcCMR3QDgsQDenbRzSjraGqDtvDKWbbVOrz/t3NJlyz+57Gr6bKnnlQf8fVFWuk2ytrQDNm/g5FKvtQHA7BMz3/G/9KL719qVYyX1FUjpslbaApLVJwvu3jEDmqWL2rba9+qvwiYrs03pCZYn9XwIwKOr9hWP6uEAPgvg1UT0ASJ6JRHdC8CDmfm2qdHbADxosj8LwM2i/C2T7hQhoufSFGj7whe+IPWnHL30nBvYq+v9BJW2S5Z6urw3MWVdVnmvLmtJJ/tNdKonpdux/to4yGWfXqrppd+SpWAEsMibsvps6aJ7493XyF7bRM9GlJ+Bs1pmiYx669cjFVDdBcBjAPwGMz8awJcxLfMcsUZlT8+Z+TJmvoCZL7jf/e636cyC+NMSSFlAmgM6Sx+BxgNJVD4CWgSkaOknoeEt/+SyzlruaThpQHlw8M7lsrVSLoJXs/XuT+U+Rh9aEeSiZyLTef1b8syPkLWC6hYAt4g9DldgA67PENGZADAdbxf254jyZwO4NWtkySeFp7Mezt5PxCjPmiDyOMerigCm65XeiHXNEawknKSuHSOPTv5Z4yAhptuvQEtfnwdAr21rzDLb3nsr72F0X3sANspOpq244lKR/y3b+xst6VUw818AuJmIHjGpngzgowCuBPDsSfdsAG+Z0lcCuJiI7kZEDwNwLoD3VjrT8wkx0i7Kyz5J29Gb2JYu8qq0fQQMqa8s9Sw4EZEJLOktaTh5f5Zn1cbLWm56S0E57tZ4ecu/Crz00bKt3G9ZPnumrGer5xmco7PaHSEd+6iGSnUf1c8AeB0R3RXAJwH8JDaQu5yIngPgUwCeMV3IR4jocmxg9g0Az2PmE1kDRH3fuZtj1x4QaRfVkdWv9ZbdaaftDaDr8u3YbHWetmui7eW5bNc7B07dE9OC601vtWm9fPDEmvRSr+HgnWfg79XL66+CxoJXBWhLgVSFkGcXgXOubANEmZRAxcwfBGBt3nqyY/9SAC+d0yE52SJgRHYSSBoUnr0HFO+ha/ZVKHnlp/Ha83BJnaxXw6nZ6/FrOg9Oss9NJ9uW0NL53n3T/dG2GkCWLvKkdH6zke1n9hm8tD4qb12j9byMCEHM1Vl9XCqrBdV+SQaTCFxRnqzfs9c3uwdA8ijraGmrvGUL7AWNVYfMO3bsGE6cOGHW0SaZtQVB7z7XEJPXFG1LsO6hFCvg3PQeJPS51FXgFdUR2Vfgo69JH632LBuv3grAsg+FyG6EHGlQeZM4ApNnp2GjbTxYWTCwYNe71JNl5eTXUNLenSwH2BADYlhZZeUYaGBZnlTvQ+5N5JbnTdBeSLWx0joPHJa97ldWt1Wvd10eyLyxaRKV0zbVukZJe2b2W1YDKiD2qCydtfyygGTBw4OV7ot8aPXyR8OgB0q6Dl3es7GWfsCpmzebVOAkr1v3Q3pS2adoNJFaX6xr12PVAylZVoJF1yPbtMp68NLldJ8rR+sa54Jsqf0o2XlUbP8EbwaWSp5uR9/kyEuK6rDsM4DJoxXD0mOg6/Bg5Y2dhFOzARB6U9bys1eiZZ/WV5d0Ml9/nzAqF+kr8IruYRaDqkAq88i8tjz7yKtdKkcWVPqGWFCQaQ0KL8+6gZH3BfiAaDe/16vybK16dVkvLiXrssSqzwqk66/QyDHSS8BW1mtPijc5KvGqbUBKgke37wXhreuoLgUjgOljBjDr3lfKR/dhqRxZUAF7gSR1EmD6mC3/Km/1vKB6r1cljxbULChZ9vJcH6XIuqK81lfL2wPybQktLwuoWxOiEq+qACGDlISRTre6I/sMdrIO3Vfv+ix9L9AykFV1I2F1pEEFnOpRjVr+WUDJYBRBLfKqpE7bWh6gPGq9VX8Eq9NO2/sfZFq/NXzkuFW2JfQ85NkbqWZj3Q/Ls2rjaOVn0MnAI9uPoCavK7PN+tMLNKnLlpi63m1B6kiDyoJOlDcKQNmN1nrPq8qgJM+9JV0lLpV5VpZYgXY5JkBtW4L3gEawlX3UYxFBoAKbJZCqvP2TfczgFY1Dz7EHaF49UbxrhOze+tGpXlPTRcHvCoCypVsVaq2c5UFZQXFvqSXr0JME+GtoRMvB6A2fvD75CSjr1zYVT6rnYY88Kw8M1oS1bDJIaQ9M22RxrKh9fR094KwCcw7I9PPl5Y2QnUellnjREqwHQBlkspsuwSPb8+q2PuGifVF6HGQ9HqxanrfU88bX8qI0bKUnNeehjCZPu4amiyahtUSUugqkvMkd6b32KvDyxmDpMXsr2I5ZAH+EHGlQATasrLw5b/WWelW6nZ63fZE+C6JnsLLEC6TLa9ZelLf0k21Ul36ezpts1r3MYjxzIdW7pcGqx4KXzvPq0tfojUVWNgLRtiF1pEGVgajnrV4r45XV+dFR12HlyWMl/pRNbKsuvdzzYKWvNwNWO2po6T5Z55nMeT0fQWAOpDIPLNPrfsixsMpE11mBoFU+eyvYA7QRcqRBBdhQiZZ/HoAyz0sv/6L6NBCsPFm3Bc1Ib7Uh67XyvLd61qed3isl7bxrX7Lsk2Ohx0UfNcil3oOAhIpefvVCSteR6aN6ojzvGczGxxrTuXWOBNWRDqZXAGTdgCwAnnlguj55jGxbuhp/8vRNB+z9pYMGmJ6lnh7PBhsPWN54V5d9+vqs82gSVl77N7sIABVIVYPquv1Ir6+rkufV3wPMOUAbIUd66ScHtPoGzvOWZH1Sb0FI2kfLQu+NXjQZI30VVk1vxZG0WP+oQV6bBlarz7p+C1LVh90aE51u16UnlUzrMVgKqR4YLfWmvLqlrRyTHvhkxyrQlsiRBVUTb4DnBsAzD83bZmD1IQqej4hLee3Iuto16KWeBJEVSJfjlsWl9FhY/czEs/fe9kldBihd3vOWdPlsmdirl/3I4moZULy/OdscdDtz7l8mRxpUEVg8qEQ3JPpU0W8ALdtq8Lyls7iU9qK8n2apeE/RUlACKgKWPo74eRfdR9mn7GgBSuZVgNIDKS8g3wsMr49Wvu5XNCY9Y9dzHCEjQEVE5wB4LYBvAXASwGXM/ArPfjWgAnJvqWoXeVWtfDtGbwtle4DvIen8qJwUC1bNnojMPGljBcjlOPXEpfTSb25Afe5Ek9fd9NaEl3YZpDIvqwIjqy+6vqi/VhtRnZ5tdMxeROjndakM8qi+AeCfMPP7ieg+AK4loncw80ct49WAKroZ2Vs9q1xLa33kKVl53nLRApV3LYAdlwJ8WLW8aKnXdNmO9Cwu5cWnemJT1vV74+GBueVZk13aRTDzvrAsy0fLuCrYIrhFkIjyrXGr1OvV49W7RNrzNqCe2wC0/wv6JSK6Dpv//7l+UEVLP8D/LlzmVUlbaxJGWxAsIHmek65L282BldU/Kx/Y+9pYQkuOS7ONxlFfV+9bP62z4NT0FpT0BO8NqPdASsOt9W3Oks/SW3XJMckAqG3lsTcwP0KKHtUZRHSNOL+MmS+zDInoodj81+SrrXxgRaAC8iWdHPzIm9ITJPLAmi7agmClo/aiIHoEq+jTKtuCoOGsr1uno5iUBajqAx/ZVfb5ZICSNj2Q8oLkvb9rVcmPYKT7r+31OFbqr/zJmOFSKYLqODNb/xDmFCGiewP4PQAvYOYvenarAJV3M62j5/1YMMo8MK3TfZD5Op296fOC6NLGEh1fi5Z6+oGRgPKgJsvJY+9/ncnECqbLdHTPW/loMso2osk5BzZeIL4HUj328hqyWJk8HoQ3BYx760dEp2MDqdcx85si21WACtg7QaMjkN+cHo+rHbP4k057SzIPlNb1ZmOR5WugtfYlkCq78L1gepNRS79sMo0OqHv5lR/fm5Pv2UfXY53rMcrKVvuwVPQLm7lCmw69CsB1zPzyzH41oMpulDzqZVoEsmhbQ2Yv9V7aAo60qwLJ87o8ALTr9QLp8tyLS2XB9HaurykSD9oybcFJXleUHrF1YS6kvDZH2FvjULWNjt59WSKDPKrHA/hxAB8mog9Oul9g5t+3jFcDKqDPq+oBkAcfD0IVmwhG1SC6zGt7qLKlnv5EswLp0lame34toRdQWqKxlf22JpiVbmUiIEQ2GYiyfVWAD7heYMprq0AtGqeeMqNk0Fu/PwVQ7thqQKUf7OyTQk7WyEbXm73RA/L9Ujod1WHV2eM9efkaXBGwLHBlGzxluvoJGk0IK2aVQUqWjSa1ZdOTX/GkRselKvb6OqVtdRw1bEfIqBhVj6wKVPrNVRabkjCIYlKAP9l1WntsVVBF/wRUnzfvyQOZJXr5pkHtztBQMwAAFidJREFUASuClbxma4Pn3IC6fsMUfTBYk0vWk01abTcKUnKJOTcuNRdS1rVW8jzbOffQk1Exql5ZDaiA3KuyJpm2rW5BsNrTusg+eptXgVXrT3WpF21B0DEp6TFZcak2JnpM9Zh5/3WmsizUeRVYtfFpOmtiSvu5nla2T8qClLbtWdZVYFKx8/ocjaVVx1I5sqDSoLG8qmYnj9pW5ln2nt5bDlbraWIFrZu+13ua810+DSwg/ldYHvi9gLp33ZG+cj+spYyX1vbepF66NUHaVD2krN3M3romqevxvPRLh5FyZEEF+J+4EUyiSeDBJwrC63x53m5+FiSPYCWXe0u3IAC1H8Xz4lJeMD06r0oGdDlO3j3tAZS2nwMpDYye5WLmoY2CWgVQety9vCUyIpjeK6sClZxUnqcUbSmwHm4rHS3pInvvYdDiwarlVZd6Ol+PVQOJbq/lW+NqQcvrq/dwWy8yMqkG09tRQ17qrcna7KKJLG0s4FRtlkKnUq8eh4oX6dXdc58yOfIxqgwyGbAqS0ArtqVtvbKeB+RtPYhgZdmOCKRv69cSon1iVj8928p9nQOoZrsUJNIuWxr2QMdqR1/HXKhF4+ON1VI50qAC9j6s0TKtOgGyJaCEnFWfzIug5OkbFDJ3uboFYU5cSubLcdHj48Wmsn/lrqUCfpm24F+ddJUYz35CquIp9b7l867Lq9urb5QcaVB5YMm2IEjd3CWg9VBYfZNtaPH0Ol/DJ3vrp/uhbWR9Vjr6FU8PUlFsqhpY13nR+Lbxkdco7SJA6fwIZBEMss2c0du26l+1P0ug5ulGympBRUQ/B+CnADCADwP4SQD3BPBGAA8FcBOAH2Hmz032lwJ4DoATAJ7PzG8rtHHKsXcLQktXloAy7XkyUipB9KaPvKdsiefZSQA1yZZ5WVzKu2Y97k3njY0UK8+zrwTT21GDR+qtSdrsRoHDg1TPTnWvnug6et426mvxxmiErBJURHQWgOcDOI+Zv0JElwO4GMB5AN7JzC8joksAXALgRUR03pR/PoCHAPgjIvp2Zj4RtHHKpGo6oL4FwUt7+dGSzgJRBi+d5wGrAis5HlY/JLSs/VLSzjt6Gzx7YNMjvcF03W51OZgFnXsg5eUDNqSiZaDuU2WJmF2HzM88zFGgqoQxtiHVpd9dANyDiL6OjSd1K4BLATxxyn8NgKsAvAjARQDewMxfBXAjEd0A4LEA3h01YN0gecx02RJQl8vOK2CqLPf08q7tTPe2HmjPyQuky3KynmYrbayjHDMdi4o+Mb3tGJZUxjeCU6u/AihpG03oCqSy4HWvJ5W1N8K+kj9KVulRMfOniehfAfgUgK8AeDszv52IHsybnxMFM99GRA+aipwF4D2iilsm3SlCRM8F8FwAOPPMM08ZVMuzsuDTswTUNvpcfwWmCqYMVloavBogIu9KwsiCm7SR6WhXugUp2b4XUJfjFIl1Ld49iODU9BGkpH1l0mrb3r92/RW4ScCO2LrgXZc1Xl6ZUbJKUBHRA7Dxkh4G4PMAfpeInhUVMXR7row3P0t6GQCcf/75PLUFeZyzBUGmsyWdNUG8+r06dLletzjzrmRfNdwkaKy4lIRYtDQExm32lPV75964yjw92bSulckm8ShIzfHAZJvV8t61zOmX1Z8RskpQAXgKgBuZ+bMAQERvAvB3AHyGiM6cvKkzAdw+2d8C4BxR/mxsloqhWA9yBqIsP8uz7KJtC00iWHnLPet6vbd9nl079+w1uCSoNIAib9MKqMs861o88fI0mGTag5Qsa01qfa5hYeVnEJDlq6ColMvAltlF1+ONwwjRH6D7JRVQfQrA44jontgs/Z4M4BoAXwbwbAAvm45vmeyvBPB6Ino5NsH0cwG8N2pADma0nANq8Sf9UHtekudxLYWVfjAseFk3u7JPygIW0PcrnlEwXY+RljkPvRVIl+nsKOvpAZQsM+cvK1/xpCw7b2k3J45lXbtnP0pWCSpmvpqIrgDwfmz+F9cHsFmy3RvA5UT0HGxg9ozJ/iO0eTP40cn+edEbPykefLIloLTVaR2M1jfNmgw9sNJeU3ULgnXtlndVAVYlLhUF01taxp+WPozROFdg1aQar9LllyynMnDMfVtYaatads7WhVGy2rd+zPxiAC9W6q9i411Z9i8F8NKejkTwsXRRvMmaJJG3421FqMBK1iOXct6/v5KgiTys6AvHup6WluUA/9cSAH9HehSb8uAVQdkDVnS/euJVFqB0vjV5eyE1FyBz92nN6b+nl57oCFmlR7VfomGQLQH1ecXGg00ELw0rL+akJfrnoZ5Ydr2/kKCXd1lMygNWEx3Qz8SDc2ZjwUkfI3BV33z1AqoKJ6usF79aCqm5WxdGyJpjVPsiehJ54JFpL14VeVtzth1ob6wHWNlS0IOY1Ld6gNovJFjLPAmjVo8eG5ke/dZPSxZM10dv0lmA0ucVaLW6egHlle0Jimf1z+mjHJ+RoAJ2HhWY9+5Cb3le2gNBBKdouSclglXTZW/3mh0A07vSN10DSuuqv5AA2L/i2Y7e5s5KQL1HdGwkApOl05Na1xtNfH3u5bX6egHVCyldbhtfwclAN0KOLKisT41K/Mmz13bWudZlAXMdYLfEe7vX/iKoVrwqCaHe4HkWTG/nvf/Pz5JsrDMwWccm1ps/mfYA5elGvxWsQqqyLMz6n/VNp0fJaoPp+yEW9a1B9tIR3Kzzyj9jkNIgBNR+Y8qTaAtC66eGltTptITXkjd+eoyWLv2ssr2wapIF13uApe/3KEhVtzG0cr1xphH/qmuEjIxREdFvAngagNuZ+ZGR7WpB1btfSusqyz0PVtkyrk366ieLho8sr8FS9ag0gKLgeQapKqCyFwEVffVeRsH1atrLH7l1oWergm7bs5PnUZkeSI0CFTB06fdbAH4NwGszw9WCqt2sarwKyL8CY90sC1ayrkhke9GSz7uxcvmm+1n1qCpv/IC9v0UF1L2qaPwsiT5Aonp63/xJXQYsXf+cv1ZH1d6DVE9AfGlcas2gYuY/IaKHVmxXDSqg7w2ehlvFqwJiWFUC5T1LQQ01XUfL17byvAorCaE5/3B06cMdlZdBdqsfPZDy0vpZ8aA2GhrR27pqbCpqL/KYsmsYIUVQnUFE14jzy3jz/d5ZsgpQWYOpB1Y/pJZdm/DeslHaaPFgJct50KoGyS3vSoMmA5al10fAf+PXdNFbv5EPdRsffc06ncGqF1Ky7cpEzvJ6lnhLIaX11a0Omd0oKYLqODNfMKrNVYAK8D0qIN4h7oFLQ0tKBKtK7Ml6u6dBEy35NMD0GFjAsmDlBct7gugy3cagyVwX35oU0QeMBaHqMQOUzKtAyZr82r536TZy+WbZyuvdNqh6YrMj5VCASgLKeiC95V20LMve8M29Gb1bEHReO9fA0ra9sALi/4os29jm0i+6x71HrQP6vric6Ze+FZzzO+zV7Q5z+jlKBgbTy3JoQAXEEPDO5wLJCpRX4eV9fUb3UYMrAhaw9xcSZLoHUlInxysCVPZwRhMhuj9zYaXr7AGUpdN1LoHU3GVipc1ekK0ZVET0O9j8SvAZRHQLgBcz86ss20MBKstL0mWlVIPoLc+DkAZjtqEzCpLLvlpLvgxYzHyHm5/tSq9CSvZLnzedN8aRWLajYQXsXZZ56SqwWp3eJM/AEZWfA6mKN9VrP0JGgYqZn1m1PRSg0ucVEPXAquX3BMqrYnlX8poqgNJLvez/9vVAyvKiDnLpJ9MWnIC93lM7VgClz/VzFU30DALVTZ+9QPKg2LsJdIREsddtyipAZT2QEagsXZYPnAqdzMOSy70qrCRMIu9KA0mW1fXIcwtcHrSAGqSqgKo8nN74RPcyApQUz3uydD3AanVbE3sEpLaxDIzai9oZJUcWVEDuAUXQsewzXTVg3sDVJny2wdMTCSgLWBpKMm0Fwa2lXrQzHej/Daq5Sz/PPgOUlMrmz3acA6zWxhwoedAY9XYvWgbK9qp1e2M8V478Wz951GkLZABKsNJLOgmr3kD5Eu+qSfSFYs9z8tIVaOlxkmMbxaZGPNy6Dq9OawNoz7EXUDrfKxcBaxsB96onVQ2qyzKj5Eh7VG2we74CU4WVpY8C5T1fnZF9y7wraaP7r228dA+sJIyW/MPR6oNZnQx6GRJ9SC2FlLS1AKXPK+Bqdc0BU1Q20s9pU5cZIUc+RiVvSM9XYCzARbCSIPK8o8rbvQYDK0iu+2fBS+o1sCwYWSCqQsqDX/QPR6Nld0WsmEj0wTMXVhVdFVCWzpr4mZ0HnVa+CigPUhVvSpbZeVQDRT4oOvBs2TXRMacMVi2vN1DuieUFep6VBS0PWO3as7iUB6d29MDVxAuoZ/9otCrZ/VsCq0gHxNsXMjhpfasvA1QGuSqgqpDqBeUI2YEKp34Ket5OFiCvwKrlt4kafc8v63eDgdeWhIqnk+fVX/GUIPPg1BNAt+JV0rYyFtU8C0YyncHKAxiQe1A6LwNW1YuqQqr6JrBSrsdDGyW7YDryzZ3SVkoEq0rcKfpnDNmf7oOESw+g5LnsE9D/f/sySGlA6XHVfe4Vq8xcWGXHJtZbPC+dwckCRRVu2qZnv1Pv270MUrsY1WDxHtrqtgOpt7yxKrCWLAUloKLloNbpcyttvThYCqkIUKMe7AxYc2HVxFveSV0GLCt/ztYFXV8PaDRQKh6Y1md9HSVHFlR6IK2HsQdW0gux6moQqHzPL+pz5l21PnjlonOZljaVX/GsQqoKqINY+sl0BKd29CDlpb3zVr830UdDyoLNXEhlntsoObKgAuZ5UVnAHIh/Xyl6u9cmfLQU9K5D2ljLQW2nz620pVuywVNDSo/RNpZ+Wu/ByyprwUkf56QjQGm7CABVSFX3SfVCqhKrGiU7UAkZBSsJnDkyx7vSeRp6HrDmwEpCC4AJrtZOy5dpmefplohVjwcoKXJ7QwSnduwFlwUond8DLVnPnD9Zvgd0rVyl7VFyZEHVbkD2qwievhJ/ksDphVYUJPfgZMWkKsDy0voIwDxG4NJjVwVUz4NZvWdaKmDy8nohJdv0IGTpIuAthVQl4N4DqW1tT1jyob9EVgEqYO9DBNjeUvQrnBmwZLDdW/JVl4JW/y1wSb11DRJY0tZK9xwBG1xN38QCmHVto0RvBPXA6cGqcox0rQ8ecCpgsgDl2UTQkeV7ADUHUnrcl8iR9agA36vK3vBZEgFr5AZPD07teiJoyfLe13Hmwgqo/1DeiH84moke6+h8W7AC6oDS51aerG/OX6V8FNSvLvdGQwo44qACbK8KmAerlt8mevQ9v2rfMu/KAlekk9dsLdHmwAoY+xtUvQ9lNKa9gJLpOZBqsgRQls22ty5UAu7VQLssM0qONKj0Higvv6q37KKlXGX5Z9UJ4JQ6msg6LZ3Ob+fVX1ZYAqkMULrPc8Uqux+wAuKvz8h0D7BavRmEeiFV9YyAOJaVwWuEeHNh27IKUMkBXQIromWB8p7+SoB5y0HLXp7rPKm3th5EcGrHXkhl0BohGbCqgLJ0HpzasZqOzlvdVRhVAdXzN3eZqPs9Qo4sqIBTH4glsKps6PTKejdTg8mKRzUbzxPS5z3pnl/xrEDKilXJcylrW/pZ9eilmD6OAJS2icrvJ6R6tzKMkCP/1q9JBVYWiDRwet7uadBkyz5t08R6K+kBy0tbsPKgpaFYgZQca33edNZ96RWrbAQreZ6BybLthVSU1kvHKpQi2PVCKSvbmzdKjrRHpaGUwarZaO9p5Fs9LR6cdF6rB7B/FK/iRUl77+hBq5UFDvZ7frovkS4CE9AHp3asgMsCY3WHuqefA6ie8nOWgaOC6bsYFfk/lFfd0CkHcb+3IHgxqQhYXtoCVwVaQG2DZ09sar+Wflo0mGR6LqwiiLU2IwhZOg94oyHVsxXB042SUaAiogsBvALAMQCvZOaXebarABWwN0bVREKjAqxWpk3gOT/bYi0FdV8rXlUELAtGFoAySAG1nelNvOuRss2lnyXWrnSZngurii56OzhHV/XGKpDq3SeVbf4cJSNARUTHAPzvAP4egFsAvI+IrmTmj1r2qwMVEMPKyo9kxFIQwB7gyX5rr6oKrPYAZUu9DFJZXksD/s8Pa49vtOilRwTLEbCKdLI/HlD0eQQdWWcPlDLIjYTUyHs6KJj+WAA3MPMnAYCI3gDgIgDrBdW11177l8eOHbv+oPvRIWcAOH7QnSjKYeorcLj6e5j6CgDfNqCOt2Fz3ZncnYiuEeeXMfNl4vwsADeL81sA/G2vslWACsD1zHzBQXeiKkR0zWHp72HqK3C4+nuY+jpKmPnCQVVZLp67phz7JaCd7GQnO6nJLQDOEednA7jVM96Baic72clByPsAnEtEDyOiuwK4GMCVnvFaln6X5SarksPU38PUV+Bw9fcw9XVVwszfIKKfxibmdQzAbzLzRzx7OojNWzvZyU520iO7pd9OdrKT1csOVDvZyU5WLwcOKiK6kIiuJ6IbiOiSFfTnHCL6YyK6jog+QkQ/O+kfSETvIKKPT8cHiDKXTv2/noi+7wD6fIyIPkBEbz0Efb0/EV1BRB+bxvi719pfIvq56Rn4MyL6HSK6+1r7eqeX3q+WjPzDJoj2CQAPB3BXAP8RwHkH3KczATxmSt8HwH8CcB6AXwZwyaS/BMC/mNLnTf2+G4CHTddzbJ/7/PMAXg/grdP5mvv6GgA/NaXvCuD+a+wvNhsSbwRwj+n8cgA/sca+HoW/g/ao7thGz8xfA9C20R+YMPNtzPz+Kf0lANdh89BehM0kw3T8wSl9EYA3MPNXmflGADdgc137IkR0NoAfAPBKoV5rX+8L4AkAXgUAzPw1Zv78WvuLzVvxexDRXQDcE5t9Pmvt651aDhpU1jb6sw6oL3uEiB4K4NEArgbwYGa+DdjADMCDJrODvoZfAfBCAPILWGvt68MBfBbAq6el6iuJ6F5r7C8zfxrAvwLwKQC3AfgCM799jX09CnLQoOraRr+fQkT3BvB7AF7AzF+MTA3dvlwDET0NwO3MfG21iKHbz/G+C4DHAPgNZn40gC9js3zy5CDH9gHYeEkPA/AQAPciomdFRQzdKp7lO4McNKi6ttHvlxDR6dhA6nXM/KZJ/RkiOnPKPxPA7ZP+IK/h8QCeTkQ3YbNsfhIR/ZuV9rW1fwszXz2dX4ENuNbY36cAuJGZP8vMXwfwJgB/Z6V9vdPLQYOqaxv9fghtfg/jVQCuY+aXi6wrATx7Sj8bwFuE/mIiuhsRPQzAuQDeux99ZeZLmflsZn4oNmP3LmZ+1hr7OvX3LwDcTESPmFRPxuZnPdbY308BeBwR3XN6Jp6MTbxyjX2988tBR/MBPBWbN2ufAPCLK+jP92Djsn8IwAenv6cC+CYA7wTw8en4QFHmF6f+Xw/g+w+o30/EX7/1W21fATwKwDXT+P5bAA9Ya38B/M8APgbgzwD8NjZv9FbZ1zv73+4rNDvZyU5WLwe99NvJTnayk1R2oNrJTnayetmBaic72cnqZQeqnexkJ6uXHah2spOdrF52oNrJTnayetmBaic72cnq5f8HLI6cZUOVHNYAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.imshow(z, cmap = plt.cm.gray)\n",
    "plt.colorbar()\n",
    "plt.title(\"image plot of $\\sqrt{x^2+y^2}$ for a grid of values\")\n",
    "plt.show"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,\n",
       "       17, 18, 19, 20, 21, 22, 23])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr = np.arange(24).reshape((4,3,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,\n",
       "       17, 18, 19, 20, 21, 22, 23])"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.reshape((2,3,4)).flatten()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2,  3],\n",
       "       [ 4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11]])"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr = np.arange(12).reshape((3,4))\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.flatten('C')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  4,  8,  1,  5,  9,  2,  6, 10,  3,  7, 11])"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.flatten('F')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.flatten('A')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])"
      ]
     },
     "execution_count": 79,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.flatten('K')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "xarr_80 = np.arange(6).reshape((2,3))\n",
    "yarr_80 = np.arange(6,12).reshape((2,3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2],\n",
       "       [ 3,  4,  5],\n",
       "       [ 6,  7,  8],\n",
       "       [ 9, 10, 11]])"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.vstack((xarr_80,yarr_80))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2,  6,  7,  8],\n",
       "       [ 3,  4,  5,  9, 10, 11]])"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.hstack((xarr_80,yarr_80))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  6],\n",
       "        [ 1,  7],\n",
       "        [ 2,  8]],\n",
       "\n",
       "       [[ 3,  9],\n",
       "        [ 4, 10],\n",
       "        [ 5, 11]]])"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dstack((xarr_80,yarr_80))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2],\n",
       "       [ 3,  4,  5],\n",
       "       [ 6,  7,  8],\n",
       "       [ 9, 10, 11]])"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.r_[xarr_80,yarr_80]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2,  6,  7,  8],\n",
       "       [ 3,  4,  5,  9, 10, 11]])"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.c_[xarr_80,yarr_80]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1, 2],\n",
       "       [0, 1, 2],\n",
       "       [3, 4, 5],\n",
       "       [3, 4, 5]])"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xarr_80.repeat(2, axis = 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 1, 1, 2, 2],\n",
       "       [3, 3, 4, 4, 5, 5]])"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xarr_80.repeat(2, axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1, 2, 0, 1, 2, 0, 1, 2],\n",
       "       [3, 4, 5, 3, 4, 5, 3, 4, 5],\n",
       "       [0, 1, 2, 0, 1, 2, 0, 1, 2],\n",
       "       [3, 4, 5, 3, 4, 5, 3, 4, 5],\n",
       "       [0, 1, 2, 0, 1, 2, 0, 1, 2],\n",
       "       [3, 4, 5, 3, 4, 5, 3, 4, 5]])"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.tile(xarr_80, (3,3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1, 2],\n",
       "       [3, 4, 7]])"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xarr_80.put([5],[7])\n",
    "xarr_80"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1, 2],\n",
       "       [3, 4, 6]])"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xarr_80.put([5],[6])\n",
    "xarr_80"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.97639406, -0.23123369, -0.01176662],\n",
       "       [-0.30283283,  0.9362489 , -0.41666533],\n",
       "       [-1.12388397, -1.07329799,  1.13238267],\n",
       "       [-1.12041076, -0.06111858, -0.68028535]])"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr_99 = np.random.randn(4,3)\n",
    "arr_99"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.24446458,  0.07225025, -0.35493309, -0.6206049 ])"
      ]
     },
     "execution_count": 100,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "row_means = arr_99.mean(1)\n",
    "row_means"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.24446458],\n",
       "       [ 0.07225025],\n",
       "       [-0.35493309],\n",
       "       [-0.6206049 ]])"
      ]
     },
     "execution_count": 101,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "row_means.reshape((4,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1.85037171e-17, -1.85037171e-17,  0.00000000e+00,  0.00000000e+00])"
      ]
     },
     "execution_count": 102,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "demeanded = arr_99 - row_means.reshape((4,1))\n",
    "demeanded.mean(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1.85037171e-17, -1.85037171e-17,  0.00000000e+00,  0.00000000e+00])"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "demeanded_103 = arr_99 - row_means.reshape((-1,1))\n",
    "demeanded_103.mean(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  0,  0,  0,  0],\n",
       "       [ 0,  1,  2,  3,  4],\n",
       "       [ 0,  2,  4,  6,  8],\n",
       "       [ 0,  3,  6,  9, 12]])"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xarr_104 = np.multiply.outer(np.arange(4), np.arange(5))\n",
    "xarr_104"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  0,  0],\n",
       "       [ 1,  5,  4],\n",
       "       [ 2, 10,  8],\n",
       "       [ 3, 15, 12]], dtype=int32)"
      ]
     },
     "execution_count": 113,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.add.reduceat(xarr_104,[0,2,4],axis = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([10, 18, 17], dtype=int32)"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xarr_107 = np.add.reduceat(np.arange(10),[0,5,8])\n",
    "xarr_107"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "随机漫步"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ -1,   0,  -1, ..., -34, -35, -34],\n",
       "       [ -1,  -2,  -1, ...,  32,  31,  30],\n",
       "       [  1,   2,   3, ..., -26, -25, -26],\n",
       "       ...,\n",
       "       [ -1,   0,  -1, ...,  16,  17,  18],\n",
       "       [ -1,  -2,  -1, ...,   0,   1,   0],\n",
       "       [ -1,   0,   1, ...,  -4,  -5,  -6]], dtype=int32)"
      ]
     },
     "execution_count": 115,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import random\n",
    "NWALKS = 5000\n",
    "NSTEPS = 1000\n",
    "RN_SEED = np.random.seed(121)\n",
    "draws = np.random.randint(0,2,size=(NWALKS,NSTEPS))\n",
    "steps = np.where(draws >0, 1, -1)\n",
    "walks = steps.cumsum(1)\n",
    "walks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "119"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "walks.max()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-103"
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "walks.min()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5000,)"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hist30 = (np.abs(walks) >=30).any(1)\n",
    "hist30"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3379"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hist30.sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([724,   0,   0, ...,   0,   0, 266], dtype=int64)"
      ]
     },
     "execution_count": 129,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "crossing_times = (np.abs(walks[hist30])>= 39).argmax(1)\n",
    "np.shape(crossing_times)\n",
    "crossing_times"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "387.984610831607"
      ]
     },
     "execution_count": 131,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "crossing_times.mean()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
